package com.all.widget.tree;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.all.ui.R;


public class TreeHelper {

	/**
	 * 传入我们的普通bean，转化为我们排序后的Node
	 * 
	 * @param datas
	 * @param defaultExpandLevel
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static <T> List<Node> getSortedNodes(List<T> datas,
			int defaultExpandLevel) throws IllegalArgumentException,
			IllegalAccessException

	{
		List<Node> result = new ArrayList<Node>();
		// 将用户数据转化为List<Node>
		List<Node> nodes = convetData2Node(datas);
		//设置节点关系
		setNodesRelation(nodes);
		
		// 拿到根节点
		List<Node> rootNodes = getRootNodes(nodes);
		
		// 排序以及设置Node间关系
		for (Node node : rootNodes)
		{
			addNode(result, node, defaultExpandLevel, 1);
		}
		
		return result;
	}
	
	private static void addNode(List<Node> result, Node node,
			int defaultExpandLevel, int i) {
		// TODO Auto-generated method stub
		result.add(node);
		if(i<defaultExpandLevel)
		{
			node.setExpand(true);
		}
		
		if(node.isLeaf())
			return;
		for(Node n :node.getChildren())
		{
			addNode(result, n,defaultExpandLevel, node.getLevel()+1);
		}
	}

	private static List<Node> getRootNodes(List<Node> nodes) {
		// TODO Auto-generated method stub
		List<Node> root = new ArrayList<Node>();
		for (Node node : nodes)
		{
			if (node.isRoot())
				root.add(node);
		}
		return root;
	}

	private static void setNodesRelation(List<Node> nodes) {
		// TODO Auto-generated method stub
		
		for (int i = 0; i < nodes.size(); i++)
		{
			Node n = nodes.get(i);
			for (int j = i + 1; j < nodes.size(); j++)
			{
				Node m = nodes.get(j);
				if(n.getId()==m.getpId())
				{
					n.getChildren().add(m);
					m.setParent(n);
				}
			}
		}
	}

	public static <T> List<Node> convetData2Node(List<T> datas) throws IllegalAccessException, IllegalArgumentException{
		List<Node> nodes = new ArrayList<Node>();
		Node node = null;
		
		for (T t : datas)
		{
			int id = -1;
			int pId = -1;
			String label = null;
			Class<? extends Object> clazz=  t.getClass();
			Field[] declaredFields = clazz.getDeclaredFields();
			for (Field f : declaredFields)
			{
				if(f.getAnnotation(TreeNodeId.class)!=null)
				{
					f.setAccessible(true);
					id = f.getInt(t);
				}else if(f.getAnnotation(TreeNodeLabel.class)!=null)
				{
					f.setAccessible(true);
					label = (String) f.get(t);
				}else if(f.getAnnotation(TreeNodePid.class)!=null)
				{
					f.setAccessible(true);
					pId = f.getInt(t);
				}else if (id != -1 && pId != -1 && label != null)
				{
					break;
				}
			}
			node = new Node(id, pId, label);
			nodes.add(node);
		}
		return nodes;
	}

	public static List<Node> filterVisibleNode(List<Node> mAllNodes) {
		// TODO Auto-generated method stub
		List<Node> result = new ArrayList<Node>();
		for(int i=0;i<mAllNodes.size();i++)
		{
			Node node = mAllNodes.get(i);
			if(node.isRoot()||node.isParentExpand())
			{
				result.add(node);
				setNodeIcon(node);
			}
		}
		return result;
		
		
	}

	private static void setNodeIcon(Node node) {
		// TODO Auto-generated method stub
		if(!node.isExpand()&&!node.isLeaf())
		{
			node.setIcon(R.drawable.tree_ec);
		}else if(node.isExpand()&&!node.isLeaf())
		{
			node.setIcon(R.drawable.tree_ex);
		}else
			node.setIcon(-1);
	}

	public static List<Node> getAllSortsNodes(String json){
		// TODO Auto-generated method stub
		List<Node> nodes = new ArrayList<Node>();
		// 将用户数据转化为List<Node>
		json2Node(nodes,json);
	
		return nodes;
	}

	private static void json2Node(List<com.all.widget.tree.Node> nodes,
			String jsonStr) {
		// TODO Auto-generated method stub
		try {
			// 返回的数据是否是树型

			JSONObject json = new JSONObject(jsonStr);
			Node node = new Node();
			node.setExpand(false);
			node.setId(Integer.parseInt(json.getString("id")));
			node.setLeaf(!json.getBoolean("isParent"));
			node.setName(json.getString("name"));
			node.setLevel(1);
			node.setParent(null);
			node.setExpand(true);
			nodes.add(node);
			// 添加子节点
			addChildNode(node,jsonStr);
			nodes.addAll(node.getChildren());
			/*// 设置节点间的关系
			if (nodes.size() > 0) {
				for (Node nd : nodes) {
					if (nd.getId() == Integer.parseInt(json.getString("pid"))) {
						node.setParent(nd);
						nd.getChildren().add(node);
						node.setpId(nd.getId());
						node.setLevel(nd.getLevel() + 1);
					}
				}
			} else {
				// 第 一个节点为根节点
				node.setLevel(1);
				node.setParent(null);
				node.setExpand(true);
				nodes.add(node);
			}*/
			// 添加子节点
			/*JSONArray nodesArray = json.getJSONArray("children");
			if (nodesArray.length() > 0) {
				// 循环读取字节点
				for (int i = 0; i < nodesArray.length(); i++) {
					// 字节点的json字条串
					String js = nodesArray.getJSONObject(i).toString();
					// 循环调用，把字符串转换成node
					json2Node(nodes, js);

				}
			}*/
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 设置图片
		for (Node n : nodes)
		{
			setNodeIcon(n);
		}
			
	}

	public static void addChildNode(Node mClickNode, String childJson) {
		// TODO Auto-generated method stub
		List<Node> childNodes = new ArrayList<Node>();
		JSONObject json;
		try {
			json = new JSONObject(childJson);
			JSONArray nodesArray = json.getJSONArray("children");
			if(nodesArray.length()>0)
			{
				//循环读取字节点
				for(int i=0;i<nodesArray.length();i++)
				{
					//字节点的json字条串
					String js = nodesArray.getJSONObject(i).toString();
					//点击的当前节点pn，添加子节点
					childNodes.add(toNode(mClickNode,js));
				}
				
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		mClickNode.addChild(childNodes);
	}
	
	/**
	 * 把字符串转换成子节点，并添加到交节点当中
	 * @param pn 父节点
	 * @param childJson 要转换成子节点的字条串
	 * @return
	 */
	public static Node toNode(Node pn,String childJson) {
		JSONObject json;
		try {
			json = new JSONObject(childJson);
			Node node=new Node();
			//node.setExpand(true);
			node.setId(Integer.parseInt(json.getString("id")));
			node.setLevel(pn.getLevel()+1);
			node.setLeaf(!json.getBoolean("isParent"));
			node.setName(json.getString("name"));
			if(pn!=null)
			{
				node.setParent(pn);		
				String pid = json.getString("pid");
				node.setpId(Integer.parseInt(pid));
			}
			return node;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
}
